```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java IO流详解 - 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
            border-radius: 8px;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
        }
        .section-title {
            position: relative;
            padding-left: 1.5rem;
        }
        .section-title:before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            height: 100%;
            width: 4px;
            background: linear-gradient(to bottom, #6e8efb, #a777e3);
            border-radius: 2px;
        }
        .code-block {
            font-family: 'Courier New', Courier, monospace;
            background-color: #f8f9fa;
            padding: 1rem;
            border-radius: 6px;
            overflow-x: auto;
        }
        .keyword {
            color: #d63384;
        }
        .class-name {
            color: #6f42c1;
        }
        .method {
            color: #005cc5;
        }
        .mermaid {
            background-color: #f8f9fa;
            padding: 1rem;
            border-radius: 8px;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl">
            <h1 class="text-4xl md:text-5xl font-bold mb-4">Java IO流深度解析</h1>
            <p class="text-xl md:text-2xl mb-8">掌握数据流动的艺术，解锁高效文件操作</p>
            <div class="flex flex-wrap gap-4">
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-file-alt mr-2"></i>
                    <span>字节流 vs 字符流</span>
                </div>
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-exchange-alt mr-2"></i>
                    <span>输入输出转换</span>
                </div>
                <div class="px-4 py-2 bg-white bg-opacity-20 rounded-full flex items-center">
                    <i class="fas fa-tachometer-alt mr-2"></i>
                    <span>性能优化技巧</span>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-4xl py-12 px-4 md:px-0">
        <!-- Section 1: IO基本概念 -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 section-title">1. IO的基本概念</h2>
            <div class="card bg-white p-6 mb-8">
                <h3 class="text-xl font-semibold mb-4 text-purple-700"><i class="fas fa-stream mr-2"></i>什么是IO流？</h3>
                <p class="mb-4">IO流（Input/Output Stream）是Java中用于处理输入输出的抽象概念。在实际应用中，几乎所有涉及到数据交换的场景都需要使用IO流，例如：</p>
                <ul class="list-disc pl-6 mb-6 space-y-2">
                    <li>文件上传/下载功能</li>
                    <li>在线阅卷系统</li>
                    <li>网络数据传输</li>
                    <li>数据库读写操作</li>
                </ul>
                
                <h3 class="text-xl font-semibold mb-4 text-purple-700"><i class="fas fa-project-diagram mr-2"></i>IO流的分类</h3>
                <div class="grid md:grid-cols-3 gap-6 mb-6">
                    <div class="card p-4 bg-blue-50">
                        <h4 class="font-semibold mb-2 text-blue-700"><i class="fas fa-arrow-right-arrow-left mr-2"></i>按方向分</h4>
                        <p>输入流 (Input)</p>
                        <p>输出流 (Output)</p>
                    </div>
                    <div class="card p-4 bg-green-50">
                        <h4 class="font-semibold mb-2 text-green-700"><i class="fas fa-ruler-combined mr-2"></i>按单位分</h4>
                        <p>字节流 (byte)</p>
                        <p>字符流 (char)</p>
                    </div>
                    <div class="card p-4 bg-purple-50">
                        <h4 class="font-semibold mb-2 text-purple-700"><i class="fas fa-cogs mr-2"></i>按功能分</h4>
                        <p>节点流</p>
                        <p>处理流</p>
                    </div>
                </div>
                
                <div class="mermaid mb-6">
                    graph LR
                    A[IO流] --> B[方向]
                    A --> C[单位]
                    A --> D[功能]
                    B --> B1[输入流]
                    B --> B2[输出流]
                    C --> C1[字节流]
                    C --> C2[字符流]
                    D --> D1[节点流]
                    D --> D2[处理流]
                </div>
            </div>
        </section>

        <!-- Section 2: 数据单位换算 -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 section-title">2. 数据单位换算</h2>
            <div class="card bg-white p-6">
                <h3 class="text-xl font-semibold mb-4 text-blue-700"><i class="fas fa-calculator mr-2"></i>计算机存储单位</h3>
                <p class="mb-4">计算机保存文件的最小单位是字节(Byte)，以下是常见的数据单位换算关系：</p>
                <div class="grid grid-cols-2 md:grid-cols-5 gap-4 mb-6">
                    <div class="text-center p-3 bg-blue-100 rounded-lg">
                        <p class="text-2xl font-bold text-blue-700">1K</p>
                        <p>= 1024字节</p>
                    </div>
                    <div class="text-center p-3 bg-green-100 rounded-lg">
                        <p class="text-2xl font-bold text-green-700">1M</p>
                        <p>= 1024K</p>
                    </div>
                    <div class="text-center p-3 bg-purple-100 rounded-lg">
                        <p class="text-2xl font-bold text-purple-700">1G</p>
                        <p>= 1024M</p>
                    </div>
                    <div class="text-center p-3 bg-yellow-100 rounded-lg">
                        <p class="text-2xl font-bold text-yellow-700">1T</p>
                        <p>= 1024G</p>
                    </div>
                    <div class="text-center p-3 bg-red-100 rounded-lg">
                        <p class="text-2xl font-bold text-red-700">1P</p>
                        <p>= 1024T</p>
                    </div>
                </div>
                
                <div class="mermaid">
                    pie
                    title 数据单位关系
                    "1K = 1024字节" : 1
                    "1M = 1024K" : 1024
                    "1G = 1024M" : 1048576
                    "1T = 1024G" : 1073741824
                    "1P = 1024T" : 1099511627776
                </div>
            </div>
        </section>

        <!-- Section 3: 字节流 -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 section-title">3. 字节流（输入、输出）</h2>
            <div class="card bg-white p-6">
                <div class="mb-6">
                    <h3 class="text-xl font-semibold mb-4 text-purple-700"><i class="fas fa-code mr-2"></i>字节流概述</h3>
                    <p class="mb-4">字节流是最早出现的流，因为计算机保存文件的最小单位就是字节。Java API为我们提供了两个字节流的基类：</p>
                    
                    <div class="grid md:grid-cols-2 gap-6 mb-6">
                        <div class="code-block">
                            <p><span class="keyword">public abstract class</span> <span class="class-name">InputStream</span></p>
                            <p class="ml-4"><span class="keyword">extends</span> Object</p>
                            <p class="ml-4"><span class="keyword">implements</span> Closeable</p>
                            <p class="mt-2">此抽象类是表示字节输入流的所有类的超类。</p>
                        </div>
                        <div class="code-block">
                            <p><span class="keyword">public abstract class</span> <span class="class-name">OutputStream</span></p>
                            <p class="ml-4"><span class="keyword">extends</span> Object</p>
                            <p class="ml-4"><span class="keyword">implements</span> Closeable, Flushable</p>
                            <p class="mt-2">此抽象类是表示输出字节流的所有类的超类。</p>
                        </div>
                    </div>
                </div>
                
                <div class="bg-yellow-50 p-4 rounded-lg border-l-4 border-yellow-400">
                    <h4 class="font-semibold text-yellow-800 mb-2"><i class="fas fa-lightbulb mr-2"></i>重点问题</h4>
                    <p>什么是输入流，什么是输出流，如何区分？</p>
                    <p class="mt-2">输入流是从数据源读取数据到程序，输出流是从程序写出数据到目标位置。可以类比为水流的方向：输入流是水流入程序，输出流是水从程序流出。</p>
                </div>
            </div>
        </section>

        <!-- Section 4: 应用驱动API学习-字节流 -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 section-title">4. 应用驱动API学习-字节流</h2>
            
            <!-- 4.1 -->
            <div class="card bg-white p-6 mb-8">
                <h3 class="text-xl font-semibold mb-4 text-purple-700">4.1 写内容到文件中</h3>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <div class="bg-blue-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-blue-700 font-bold">1</span>
                        </div>
                        <div>
                            <p class="font-medium">对异常直接抛出，不处理的方式</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">main</span>(String[] args) <span class="keyword">throws</span> IOException {</p>
                                <p class="ml-4">OutputStream os = <span class="keyword">new</span> FileOutputStream(<span class="string">"test.txt"</span>);</p>
                                <p class="ml-4">os.write(<span class="string">"Hello World"</span>.getBytes());</p>
                                <p class="ml-4">os.close();</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-green-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-green-700 font-bold">2</span>
                        </div>
                        <div>
                            <p class="font-medium">采用标准处理异常的方式</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">main</span>(String[] args) {</p>
                                <p class="ml-4"><span class="keyword">try</span> (OutputStream os = <span class="keyword">new</span> FileOutputStream(<span class="string">"test.txt"</span>)) {</p>
                                <p class="ml-8">os.write(<span class="string">"Hello World"</span>.getBytes());</p>
                                <p class="ml-4">} <span class="keyword">catch</span> (IOException e) {</p>
                                <p class="ml-8">e.printStackTrace();</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-purple-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-purple-700 font-bold">3</span>
                        </div>
                        <div>
                            <p class="font-medium">实现对文件内容的追加</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">main</span>(String[] args) {</p>
                                <p class="ml-4"><span class="keyword">try</span> (OutputStream os = <span class="keyword">new</span> FileOutputStream(<span class="string">"test.txt"</span>, <span class="keyword">true</span>)) {</p>
                                <p class="ml-8">os.write(<span class="string">"\\nAppended Content"</span>.getBytes());</p>
                                <p class="ml-4">} <span class="keyword">catch</span> (IOException e) {</p>
                                <p class="ml-8">e.printStackTrace();</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-red-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-red-700 font-bold">4</span>
                        </div>
                        <div>
                            <p class="font-medium">如果文件不存在，会出现什么情况？</p>
                            <p class="mt-2">当使用FileOutputStream写入文件时，如果文件不存在，会自动创建该文件（前提是路径有效且有权限）。如果是读取不存在的文件，则会抛出FileNotFoundException。</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 4.2 -->
            <div class="card bg-white p-6 mb-8">
                <h3 class="text-xl font-semibold mb-4 text-purple-700">4.2 读取文件的内容</h3>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <div class="bg-blue-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-blue-700 font-bold">1</span>
                        </div>
                        <div>
                            <p class="font-medium">采用逐个字节的读取方式</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">main</span>(String[] args) {</p>
                                <p class="ml-4"><span class="keyword">try</span> (InputStream is = <span class="keyword">new</span> FileInputStream(<span class="string">"test.txt"</span>)) {</p>
                                <p class="ml-8"><span class="keyword">int</span> data;</p>
                                <p class="ml-8"><span class="keyword">while</span> ((data = is.read()) != -1) {</p>
                                <p class="ml-12">System.out.print((<span class="keyword">char</span>) data);</p>
                                <p class="ml-8">}</p>
                                <p class="ml-4">} <span class="keyword">catch</span> (IOException e) {</p>
                                <p class="ml-8">e.printStackTrace();</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-green-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-green-700 font-bold">2</span>
                        </div>
                        <div>
                            <p class="font-medium">如果文件不存在，会出现什么情况</p>
                            <p class="mt-2">当尝试读取不存在的文件时，会抛出FileNotFoundException异常。因此在实际开发中，通常需要先检查文件是否存在或者捕获该异常进行处理。</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 4.3 -->
            <div class="card bg-white p-6 mb-8">
                <h3 class="text-xl font-semibold mb-4 text-purple-700">4.3 完成文件的拷贝功能</h3>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <div class="bg-blue-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-blue-700 font-bold">1</span>
                        </div>
                        <div>
                            <p class="font-medium">完成普通文本文件的拷贝</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">copyFile</span>(String src, String dest) <span class="keyword">throws</span> IOException {</p>
                                <p class="ml-4"><span class="keyword">try</span> (InputStream is = <span class="keyword">new</span> FileInputStream(src);</p>
                                <p class="ml-8">OutputStream os = <span class="keyword">new</span> FileOutputStream(dest)) {</p>
                                <p class="ml-8"><span class="keyword">int</span> data;</p>
                                <p class="ml-8"><span class="keyword">while</span> ((data = is.read()) != -1) {</p>
                                <p class="ml-12">os.write(data);</p>
                                <p class="ml-8">}</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-green-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-green-700 font-bold">2</span>
                        </div>
                        <div>
                            <p class="font-medium">完成二进制文件的拷贝（图片、视频等）</p>
                            <p class="mt-2">二进制文件的拷贝与文本文件类似，但需要注意使用字节流而非字符流。对于大文件，建议使用缓冲区提高效率（见4.4节）。</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 4.4 -->
            <div class="card bg-white p-6">
                <h3 class="text-xl font-semibold mb-4 text-purple-700">4.4 优化文件的读写性能</h3>
                <div class="space-y-4">
                    <div class="flex items-start">
                        <div class="bg-blue-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-blue-700 font-bold">1</span>
                        </div>
                        <div>
                            <p class="font-medium">使用数组提升读写效率</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">copyFileWithBuffer</span>(String src, String dest) <span class="keyword">throws</span> IOException {</p>
                                <p class="ml-4"><span class="keyword">try</span> (InputStream is = <span class="keyword">new</span> FileInputStream(src);</p>
                                <p class="ml-8">OutputStream os = <span class="keyword">new</span> FileOutputStream(dest)) {</p>
                                <p class="ml-8"><span class="keyword">byte</span>[] buffer = <span class="keyword">new</span> <span class="keyword">byte</span>[1024]; <span class="comment">// 1KB缓冲区</span></p>
                                <p class="ml-8"><span class="keyword">int</span> len;</p>
                                <p class="ml-8"><span class="keyword">while</span> ((len = is.read(buffer)) != -1) {</p>
                                <p class="ml-12">os.write(buffer, 0, len);</p>
                                <p class="ml-8">}</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="bg-green-100 rounded-full w-8 h-8 flex items-center justify-center mr-3 mt-1 flex-shrink-0">
                            <span class="text-green-700 font-bold">2</span>
                        </div>
                        <div>
                            <p class="font-medium">使用缓冲流（BufferedInputStream/BufferedOutputStream）</p>
                            <div class="code-block mt-2">
                                <p><span class="keyword">public static void</span> <span class="method">copyFileWithBufferedStream</span>(String src, String dest) <span class="keyword">throws</span> IOException {</p>
                                <p class="ml-4"><span class="keyword">try</span> (BufferedInputStream bis = <span class="keyword">new</span> BufferedInputStream(<span class="keyword">new</span> FileInputStream(src));</p>
                                <p class="ml-8">BufferedOutputStream bos = <span class="keyword">new</span> BufferedOutputStream(<span class="keyword">new</span> FileOutputStream(dest))) {</p>
                                <p class="ml-8"><span class="keyword">byte</span>[] buffer = <span class="keyword">new</span> <span class="keyword">byte</span>[8192]; <span class="comment">// 8KB缓冲区</span></p>
                                <p class="ml-8"><span class="keyword">int</span> len;</p>
                                <p class="ml-8"><span class="keyword">while</span> ((len = bis.read(buffer)) != -1) {</p>
                                <p class="ml-12">bos.write(buffer, 0, len);</p>
                                <p class="ml-8">}</p>
                                <p class="ml-4">}</p>
                                <p>}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="mt-6">
                        <div class="mermaid">
                            classDiagram
                                class InputStream {
                                    <<abstract>>
                                    +read() int
                                    +close() void
                                }
                                class OutputStream {
                                    <<abstract>>
                                    +write(int) void
                                    +close() void
                                    +flush() void
                                }
                                class FilterInputStream {
                                    -in InputStream
                                }
                                class FilterOutputStream {
                                    -out OutputStream
                                }
                                class BufferedInputStream {
                                    -buf byte[]
                                }
                                class BufferedOutputStream {
                                    -buf byte[]
                                }
                                class FileInputStream {
                                    +FileInputStream(String)
                                }
                                class FileOutputStream {
                                    +FileOutputStream(String)
                                }
                                
                                InputStream <|-- FilterInputStream
                                FilterInputStream <|-- BufferedInputStream
                                InputStream <|-- FileInputStream
                                
                                OutputStream <|-- FilterOutputStream
                                FilterOutputStream <|-- BufferedOutputStream
                                OutputStream <|-- FileOutputStream
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Section 5: 作业 -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 section-title">5. 作业</h2>
            <div class="card bg-white p-6">
                <h3 class="text-xl font-semibold mb-4 text-purple-700"><i class="fas fa-tasks mr-2"></i>课后练习</h3>
                <ul class="space-y-3">
                    <li class="flex items-start">
                        <span class="bg-blue-100 text-blue-700 rounded-full w-6 h-6 flex items-center justify-center mr-3 mt-1 flex-shrink-0">1</span>
                        <div>
                            <p class="font-medium">基础流与字节缓冲流读写数据的性能测试整理</p>
                            <p class="text-sm text-gray-600 mt-1">比较两种方式在读取大文件时的效率差异</p>
                        </div>
                    </li>
                    <li class="flex items-start">
                        <span class="bg-green-100 text-green-700 rounded-full w-6 h-6 flex items-center justify-center mr-3 mt-1 flex-shrink-0">2</span>
                        <div>
                            <p class="font-medium">验证缓冲区已满后，会自动将缓冲区数据写入磁盘文件</p>
                            <p class="text-sm text-gray-600 mt-1">通过实验观察缓冲流的工作机制</p>
                        </div>
                    </li>
                    <li class="flex items-start">
                        <span class="bg-purple-100 text-purple-700 rounded-full w-6 h-6 flex items-center justify-center mr-3 mt-1 flex-shrink-0">3</span>
                        <div>
                            <p class="font-medium">实现文件夹的拷贝（包含多层子目录和多种类型的文件）</p>
                            <p class="text-sm text-gray-600 mt-1">结合递归算法完成目录结构的复制</p>
                        </div>
                    </li>
                </ul>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-8">
        <div class="container mx-auto max-w-4xl px-4">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h3 class="text-xl font-bold">技术小馆</h3>
                    <p class="text-gray-400">探索技术的无限可能</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-gray-300 hover:text-white transition-colors duration-200">
                        <i class="fas fa-link mr-2"></i>www.yuque.com/jtostring
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-6 pt-6 text-center text-gray-400 text-sm">
                &copy; 2023 技术小馆. 保留所有权利.
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```